package cn.dota2info.elk.utils;


import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.concurrent.*;
import java.util.function.Function;

public class JucUtils {
    /**
     * 使用CoutdownLatch来实现多线程分开处理，后汇总
     * @param f1
     * @param o1
     * @param f2
     * @param o2
     * @param f3
     * @throws InterruptedException
     */
    public static void dealByMulti(Function f1,Object o1,Function f2,Object o2,Function<Data,Object> f3) throws InterruptedException {
        ExecutorService service=Executors.newFixedThreadPool(2);
        CountDownLatch latch=new CountDownLatch(2);
        Data data=new Data();
        service.execute(()->{
            data.setO1(f1.apply(o1));
            latch.countDown();

        });
        service.execute(()->{
            data.setO2(f2.apply(o2));
            latch.countDown();

        });
        latch.await();
        f3.apply(data);
        service.shutdown();
    }

    /**
     * 起跑问题
     * @throws Exception
     */
    public static void dealByCircle() throws Exception {
        CyclicBarrier barrier=new CyclicBarrier(3);
        CountDownLatch latch=new CountDownLatch(2);
        ExecutorService service=Executors.newFixedThreadPool(2);
        Data data=new Data();
        service.execute(()->{
            try {
                Thread.sleep(5000);
                System.out.println("player1 ready");
                barrier.await();
                Time time=new Time();
                System.out.println("player1 start run");
                Thread.sleep(2000);
                System.out.println("player1 end total time:"+time.getTime());
                latch.countDown();
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        service.execute(()->{
            try {
                Thread.sleep(3000);
                System.out.println("player2 ready");
                barrier.await();
                Time time=new Time();
                System.out.println("player2 start run");
                Thread.sleep(3500);
                System.out.println("player2 end total time:"+time.getTime());
                latch.countDown();
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        barrier.await();
        Time time=new Time();
        latch.await();
        System.out.println("complete run !");
        System.out.println("total match time:"+time.getTime() +"second");

        service.shutdown();


    }
    private static String getTime(Long start,Long end){
        BigDecimal decimal=new BigDecimal(end);
        return decimal.subtract(new BigDecimal(start)).divide(new BigDecimal(1000)).toString();

    }
    public static void main(String[] args) throws Exception {
//        JucUtils.dealByMulti(s-> s+"1","hello", s->s+"2","world", JucUtils::apply);
        int i=0;
        while (i<3){
            JucUtils.dealByCircle();
            i++;
        }
    }

    private static Object apply(Data s) {
        System.out.println(s.getO1().toString() + s.getO2());
        return null;
    }

}
class Data{
    private Object o1;
    private Object o2;

    public Object getO1() {
        return o1;
    }

    public void setO1(Object o1) {
        this.o1 = o1;
    }

    public Object getO2() {
        return o2;
    }

    public void setO2(Object o2) {
        this.o2 = o2;
    }
}

class Time{
    private  Long startTime;

    public Time() {
      startTime=System.currentTimeMillis();
        System.out.println("start time:"+startTime);
    }

    public  String getTime(){
        BigDecimal decimal=new BigDecimal(System.currentTimeMillis());
        System.out.println("end time:"+decimal);
        return decimal.subtract(new BigDecimal(startTime)).divide(new BigDecimal(1000),2, RoundingMode.HALF_UP).toString();

    }
}
